%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% mdlt2
function [coefs,avgres] = mdlt2(frame,xypts)

% function [coefs,avgres] = mdlt2(frame,xypts)
%
% An alternative Modified Direct Linear Transformation implementation - see
% also mdlt1 from Tomislav Pribanic.  This one takes a bit more cpu time
% but doesn't require Matlab's symbolic solver or very lengthy equations
% keyed in by hand.
%
% Modified Direct Linear Transformation (Hatze, 1988) recognizes an
% internal non-linear dependency in the DLT algorithm, potentially
% resulting in a more accurate reconstruction.  In practice, this is rarely
% the case.  Contrary to the results in Hatze (1988) I've never found a
% test case, either in extrapolation outside the calibration volume or
% reconstruction within it, where mDLT consistently outperformed standard
% DLT.
%
% However, all modified DLT solutions internally express rotations about
% orthogonal axes (this is not true of DLT, where the axes are usually
% non-orthogonal) - this property is very useful when recreating scenes
% in 3D visualization or graphics packages that cannot perform rotations
% about non-orthogonal axes.
%
% Ty Hedrick, Feb. 16, 2007
%
% Hatze, H. "High-precision three-dimensional photogrammetric calibration
% and object space reconstruction using a modified DLT-approach." J.
% Biomechanics, 1988, 21, 533-538

% remove any NaN points
idx=find(isnan(xypts(:,1))==true);
xypts(idx,:)=[];
frame(idx,:)=[];

% start with standard DLT coefficients
[Cinit] = dlt_computeCoefficients(frame,xypts);

% options for the Matlab optimization implementation.
opts=optimset;
opts.MaxFunEvals=1e24;
opts.MaxIter=1e24;

% search for a set of optimized DLT coefficients that adhere to the
% non-linear constraint
[Csearch] = fminsearch(@mdltScore,Cinit(2:11),opts,frame,xypts);

% get the final values
[avgres,coefs] = mdltScore(Csearch,frame,xypts);